using Domain;
using Domain.BOM;
using Domain.Quality;
using Domain.工艺工序;
using Domain.生产订单;
using Infratructure;
using Microsoft.AspNetCore.SignalR;
using Team.API.Hubs;
using Yitter.IdGenerator;
using MediatR;
using Team.API.Applocation.Command.排程;
using BackData;

namespace Team.API.Services
{
    /// <summary>
    /// 自动排程后台服务
    /// 定期检查待排程订单，自动分配设备并创建生产计划
    /// </summary>
    public class AutoSchedulingBackgroundService : BackgroundService
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly IHubContext<EquipmentStatusHub> _hubContext;
        private readonly ILogger<AutoSchedulingBackgroundService> _logger;
        private readonly TimeSpan _interval = TimeSpan.FromMinutes(2); // 每2分钟执行一次

        public AutoSchedulingBackgroundService(
            IServiceProvider serviceProvider,
            IHubContext<EquipmentStatusHub> hubContext,
            ILogger<AutoSchedulingBackgroundService> logger)
        {
            _serviceProvider = serviceProvider;
            _hubContext = hubContext;
            _logger = logger;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation("自动排程服务已启动");

            // 延迟20秒后开始执行，避免与其他服务冲突
            await Task.Delay(TimeSpan.FromSeconds(20), stoppingToken);

            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    await PerformAutoScheduling(stoppingToken);
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "自动排程时发生错误");
                }

                // 等待指定时间后再次执行
                await Task.Delay(_interval, stoppingToken);
            }

            _logger.LogInformation("自动排程服务已停止");
        }

        /// <summary>
        /// 执行自动排程
        /// </summary>
        private async Task PerformAutoScheduling(CancellationToken cancellationToken)
        {
            using var scope = _serviceProvider.CreateScope();

            var mediator = scope.ServiceProvider.GetRequiredService<IMediator>();
            var orderRepo = scope.ServiceProvider.GetRequiredService<IRepository<OrderModel>>();
            var scheduleRepo = scope.ServiceProvider.GetRequiredService<IRepository<Productionschedulemodel>>();
            var equipmentStatusService = scope.ServiceProvider.GetRequiredService<IEquipmentStatusService>();

            var currentTime = DateTime.Now;
            _logger.LogInformation($"========== 开始自动排程 - {currentTime:yyyy-MM-dd HH:mm:ss} ==========");

            try
            {
                // 步骤1: 检查并更新设备状态
                _logger.LogInformation("步骤1: 检查设备状态...");
                var (updatedCount, equipmentNames) = await equipmentStatusService.CheckAndUpdateEquipmentStatusAsync(
                    "自动排程",
                    cancellationToken);

                if (updatedCount > 0)
                {
                    _logger.LogInformation($"已更新 {updatedCount} 个设备状态: {string.Join(", ", equipmentNames)}");
                }

                // 步骤2: 获取待排程订单数量
                _logger.LogInformation("步骤2: 查找待排程订单...");
                var pendingOrderCount = await orderRepo.GetAll()
                    .Where(x => !x.IsDel && x.Orderstatus == 0)
                    .CountAsync();

                if (pendingOrderCount == 0)
                {
                    _logger.LogInformation("没有待排程订单");
                    return;
                }

                _logger.LogInformation($"找到 {pendingOrderCount} 个待排程订单");

                // 步骤3: 调用 CreateProductionCommand 执行排程
                _logger.LogInformation("步骤3: 执行排程...");
                var command = new CreateProductionCommand();
                var result = await mediator.Send(command, cancellationToken);

                if (result.Code == StateCode.OK)
                {
                    _logger.LogInformation($"排程成功: {result.Message}");

                    // 获取本次创建的排程详情
                    var recentSchedules = await scheduleRepo.GetAll()
                        .Where(x => !x.IsDel)
                        .OrderByDescending(x => x.Id)
                        .Take(result.Result)
                        .ToListAsync();

                    // 获取排程的订单信息
                    var orderIds = recentSchedules.Select(x => x.OrderId).Distinct().ToList();
                    var scheduledOrders = await orderRepo.GetAll()
                        .Where(x => orderIds.Contains(x.Id))
                        .ToListAsync();

                    // 构建详情信息
                    var schedulingDetails = scheduledOrders.Select(order =>
                    {
                        var orderSchedules = recentSchedules.Where(x => x.OrderId == order.Id).ToList();
                        return new
                        {
                            OrderId = order.Id,
                            Goodsname = "产品", // 简化信息
                            Number = order.Number,
                            ProcessCount = orderSchedules.Count,
                            Equipments = orderSchedules.Select(s => $"设备{s.Equipmentid}").Distinct().ToList(),
                            StartTime = orderSchedules.Min(x => x.Planstatetime),
                            EndTime = orderSchedules.Max(x => x.Planendtime)
                        };
                    }).ToList();

                    // 推送排程结果
                    var message = $"自动排程完成：{result.Message}";
                    await _hubContext.Clients.All.SendAsync(
                        "ReceiveAutoSchedulingComplete",
                        new
                        {
                            Time = currentTime,
                            ScheduledOrderCount = scheduledOrders.Count,
                            CreatedScheduleCount = result.Result,
                            Message = message,
                            Details = schedulingDetails
                        },
                        cancellationToken);

                    _logger.LogInformation("排程结果已通过SignalR推送");
                }
                else
                {
                    _logger.LogWarning($"排程失败: {result.Message}");
                    
                    await _hubContext.Clients.All.SendAsync(
                        "ReceiveAutoSchedulingWarning",
                        new
                        {
                            Time = currentTime,
                            Message = result.Message,
                            PendingOrderCount = pendingOrderCount
                        },
                        cancellationToken);
                }

                _logger.LogInformation($"========== 自动排程完成 ==========");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "自动排程失败");

                await _hubContext.Clients.All.SendAsync(
                    "ReceiveAutoSchedulingError",
                    new
                    {
                        Time = currentTime,
                        Message = $"自动排程失败: {ex.Message}"
                    },
                    cancellationToken);
            }
        }
    }
}
